package com.secsbrain.cmdb.web.controller;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import com.baomidou.mybatisplus.plugins.Page;
import com.secsbrain.cmdb.biz.IAppSystemService;
import com.secsbrain.cmdb.biz.IAppTypeService;
import com.secsbrain.cmdb.remote.SsoRemoteService;
import com.secsbrain.common.EnumDefinition;
import com.secsbrain.cmdb.dal.model.AppEnv;
import com.secsbrain.cmdb.dal.model.Host;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.util.Assert;
import org.springframework.web.bind.annotation.RestController;

import com.secsbrain.cmdb.biz.IAppEnvService;
import com.secsbrain.cmdb.biz.impl.CommonService;
import com.secsbrain.cmdb.biz.utils.HostUtils;
import com.secsbrain.common.ResponseVo;
import com.secsbrain.cmdb.client.iface.AppInfoService;
import com.secsbrain.cmdb.client.model.App;
import com.secsbrain.cmdb.client.model.AppDetail;
import com.secsbrain.cmdb.client.model.AppTypeDto;
import com.secsbrain.cmdb.client.model.BizType;
import com.secsbrain.cmdb.client.model.Server;
import com.secsbrain.cmdb.dal.model.AppSystem;
import com.secsbrain.cmdb.dal.model.AppType;


/**
 * 应用信息api
 *
 * @author zhaoyi
 */
@RestController
@EnableEurekaClient
public class AppInfoServiceImpl implements AppInfoService {

    private static final Logger logger = LoggerFactory.getLogger(AppInfoServiceImpl.class);

    @Autowired
    IAppTypeService appTypeService;

    @Autowired
    IAppSystemService appSystemService;

    @Autowired
    IAppEnvService envService;

    @Autowired
    SsoRemoteService userServiceFacade;

    @Autowired
    CommonService commonService;

    public ResponseVo<List<BizType>> queryAllBizList() {
        Map<Long, List<App>> appTypeMap = appSystemService.getAppTypeMap(null, false);
        return ResponseVo.getSuccessResponse(parseBizTypeDto(appTypeMap));
    }

    private List<BizType> parseBizTypeDto(Map<Long, List<App>> appTypeMap) {
        List<AppType> appTypeList = appTypeService.selectList(new AppType());
        List<BizType> bizTypeList = new ArrayList<>();
        for (AppType appType : appTypeList) {
            BizType bizType = new BizType();
            bizType.setId(appType.getId());
            bizType.setName(appType.getDepartment() + "-" + appType.getName());
            if (appTypeMap.containsKey(appType.getId())) {
                bizType.setApps(appTypeMap.get(appType.getId()));
                bizTypeList.add(bizType);
            }
        }
        return bizTypeList;
    }

    /* (non-Javadoc)
     * @see AppInfoService#queryBizListByUserId(java.lang.Long)
     */
    @Override
    public ResponseVo<List<BizType>> queryBizListByUserId(Long userId) {
        logger.debug("用户Id查询业务类型列表,userId:{}", userId);

        Assert.notNull(userId, "userId不能为空");
        Map<Long, List<App>> appTypeMap = appSystemService.getAppTypeMap(userId, false);
        return ResponseVo.getSuccessResponse(parseBizTypeDto(appTypeMap));
    }


    /* (non-Javadoc)
     * @see AppInfoService#queryAppType()
     */
    @Override
    public ResponseVo<List<AppTypeDto>> queryAppType() {
        AppType params = new AppType();
        List<AppType> list = appTypeService.selectList(params);
        List<AppTypeDto> resList = new ArrayList<AppTypeDto>();
        for (AppType appType : list) {
            AppTypeDto appTypeDto = new AppTypeDto();
            appTypeDto.setName(appType.getDepartment() + "-" + appType.getName());
            appTypeDto.setId(appType.getId());
            resList.add(appTypeDto);
        }
        return ResponseVo.getSuccessResponse(resList);
    }

    /* (non-Javadoc)
     * @see AppInfoService#queryOwnerByAppId(java.lang.Long)
     */
    @Override
    public ResponseVo<Long> queryOwnerByAppId(Long appId) {
        logger.debug("通过应用ID查询owner信息,appId:{}", appId);
        Assert.notNull(appId, "appId不能为空");

        AppSystem appSystem = appSystemService.selectById(appId);
        Assert.notNull(appSystem, "没有查询到相关应用");

        Long ownerId = appSystem.getOwnerId();
        return ResponseVo.getSuccessResponse(ownerId);
    }

    /* (non-Javadoc)
     * @see AppInfoService#queryQualityByAppId(java.lang.Long)
     */
    @Override
    public ResponseVo<Long> queryQualityByAppId(Long appId) {
        logger.debug("通过应用ID查询质量负责人信息,appId:{}", appId);
        Assert.notNull(appId, "appId不能为空");

        AppSystem appSystem = appSystemService.selectById(appId);
        Assert.notNull(appSystem, "没有查询到相关应用");

        Long qualityId = appSystem.getQualityId();
        return ResponseVo.getSuccessResponse(qualityId);
    }

    /* (non-Javadoc)
     * @see AppInfoService#isOwner(java.lang.Long, java.lang.Long)
     */
    @Override
    public ResponseVo<Boolean> isOwner(Long appId, Long userId) {
        logger.debug("查询是否是某应用的owner,appId:{},userId:{}", appId, userId);
        Assert.notNull(appId, "appId不能为空");
        Assert.notNull(userId, "userId不能为空");

        AppSystem appSystem = appSystemService.selectById(appId);
        Assert.notNull(appSystem, "没有查询到相关应用");
        return ResponseVo.getSuccessResponse(userId.equals(appSystem.getOwnerId()));
    }

    /* (non-Javadoc)
     * @see AppInfoService#getOwnerBiz(java.lang.Long)
     */
    @Override
    public ResponseVo<List<BizType>> getOwnerBiz(Long userId) {
        logger.debug("用户Id查询owner业务类型列表,userId:{}", userId);

        Map<Long, List<App>> appTypeMap = appSystemService.getAppTypeMap(userId, true);
        return ResponseVo.getSuccessResponse(parseBizTypeDto(appTypeMap));
    }

    /* (non-Javadoc)
     * @see AppInfoService#queryAppById(java.lang.Long)
     */
    @Override
    public ResponseVo<AppDetail> queryAppDetailById(Long appId) {
        Assert.notNull(appId, "appId不能为空");

        AppSystem appSystem = appSystemService.selectById(appId);

        Assert.notNull(appSystem, "没有查询到相关应用");
        return ResponseVo.getSuccessResponse(parseAppDetail(appSystem));
    }

    private AppDetail parseAppDetail(AppSystem appSystem) {
        AppDetail app = new AppDetail();
        app.setTenantCode(appSystem.getTenantCode());
        app.setId(appSystem.getId());
        app.setName(appSystem.getName());
        app.setOwnerName(appSystem.getOwnerName());
        app.setServerList(getServerList(appSystem.getHostIds(), appSystem.getK8sEnvs()));
        app.setSystemType(appSystem.getSystemType());
        Map<Long, AppType> appTypeMap = appTypeService.getAllAppType();
        app.setNameSpace(appTypeMap.get(appSystem.getTypeId()).getName());
        app.setLevel(appSystem.getLevel());
        app.setDesc(appSystem.getComment());
        app.setGitUrl(appSystem.getGitUrl());
        app.setOwnerId(appSystem.getOwnerId());
        app.setDeveloperIdList(this.parseDeveloperIdList(appSystem.getDevelopIds()));
        app.setQualityName(appSystem.getQualityName());
        app.setQualityId(appSystem.getQualityId());
        return app;
    }

    private List<Long> parseDeveloperIdList(String developIds) {
        List<Long> developerIdList = new ArrayList<>();
        if (StringUtils.isNotEmpty(developIds)) {
            if (developIds.contains(",")) {
                String[] developIdArray = developIds.split(",");
                for (String developId : developIdArray) {
                    developerIdList.add(Long.parseLong(developId));
                }
            } else {
                developerIdList.add(Long.parseLong(developIds));
            }
        }
        return developerIdList;
    }

    /* (non-Javadoc)
     * @see AppInfoService#queryAppDetailByIds(java.lang.Long[])
     */
    @Override
    public ResponseVo<List<AppDetail>> queryAppDetailByIds(Long[] appIds) {
        List<AppDetail> resultList = new ArrayList<>();
        if (appIds == null || appIds.length <= 0) {
            return ResponseVo.getSuccessResponse(resultList);
        }

        List<Long> ids = new ArrayList<>();
        for (Long appId : appIds) {
            ids.add(appId);
        }
        List<AppSystem> list = appSystemService.selectBatchIds(ids);
        for (AppSystem appSystem : list) {
            resultList.add(parseAppDetail(appSystem));
        }

        return ResponseVo.getSuccessResponse(resultList);
    }

    private List<Server> getServerList(String ids, String k8sEnvs) {
        List<Server> serverList = new ArrayList<Server>();

        if (StringUtils.isNotEmpty(ids)) {
            List<Long> hostIds = new ArrayList<Long>();
            if (ids.contains(",")) {
                for (String id : ids.split(",")) {
                    hostIds.add(Long.parseLong(id));
                }
            } else {
                hostIds.add(Long.parseLong(ids));
            }

            Map<Long, Host> hostMap = commonService.getHostMap();

            for (Long hostId : hostIds) {
                Server server = new Server();
                server.setEnvName(hostMap.get(hostId).getEnv());
                server.setIpList(HostUtils.getIpList(hostMap.get(hostId).getIp()));
                server.setHostName(hostMap.get(hostId).getHostName());
                server.setGroupName(hostMap.get(hostId).getGroupName());
                server.setHostId(hostId);

                serverList.add(server);
            }
        }

        if (StringUtils.isNotEmpty(k8sEnvs)) {
            if (k8sEnvs.contains(",")) {
                for (String k8sEnv : k8sEnvs.split(",")) {
                    Server server = new Server();
                    server.setEnvName(k8sEnv);
                    server.setHostName(Server.K8S_HOSTNAME);
                    server.setK8s(true);
                    serverList.add(server);
                }
            } else {
                Server server = new Server();
                server.setEnvName(k8sEnvs);
                server.setHostName(Server.K8S_HOSTNAME);
                server.setK8s(true);
                serverList.add(server);
            }
        }

        return serverList;
    }

    /* (non-Javadoc)
     * @see AppInfoService#queryAllAppList()
     */
    @Override
    public ResponseVo<List<App>> queryAllAppList(Integer page, Integer limit,
                                                 String sortBy, String descending, String appName, String systemType) {
        if (page == null) {
            page = 1;
        }
        if (limit == null) {
            limit = 10;
        }

        AppSystem appSystemParam = new AppSystem();
        if (StringUtils.isNotEmpty(appName)) {
            appSystemParam.setName(appName);
        }
        if (StringUtils.isNotEmpty(systemType)) {
            appSystemParam.setSystemType(systemType);
        }

        Page<AppSystem> pageBean = new Page<>(page, limit);
        String orderCondition = sortBy + " " + (Boolean.parseBoolean(descending) ? "desc" : "asc");
        if (StringUtils.isEmpty(sortBy) || "null".equals(sortBy)) {
            orderCondition = "create_time desc";
        }

        Page<AppSystem> pageResult = appSystemService.queryAppSystemPageList(pageBean, appSystemParam, orderCondition);
        List<App> resList = new ArrayList<>();
        for (AppSystem appSystem : pageResult.getRecords()) {
            App app = new App();
            app.setId(appSystem.getId());
            app.setName(appSystem.getName());
            app.setOwnerName(appSystem.getOwnerName());
            app.setOwnerId(appSystem.getOwnerId());
            app.setDeveloperIdList(this.parseDeveloperIdList(appSystem.getDevelopIds()));
            app.setSystemType(appSystem.getSystemType());
            resList.add(app);
        }
        return ResponseVo.getSuccessResponse(pageResult.getTotal(), resList);
    }

    /* (non-Javadoc)
     * @see AppInfoService#queryAppListByType(java.lang.String)
     */
    @Override
    public ResponseVo<List<App>> queryAppListByType(String[] typeArray) {
        List<AppSystem> appSystemList = appSystemService.queryAppSystemByTypes(typeArray);
        List<App> resList = new ArrayList<App>();
        for (AppSystem appSystem : appSystemList) {
            App app = new App();
            app.setId(appSystem.getId());
            app.setName(appSystem.getName());
            app.setOwnerName(appSystem.getOwnerName());
            app.setSystemType(appSystem.getSystemType());
            resList.add(app);
        }
        return ResponseVo.getSuccessResponse(resList);
    }

    /* (non-Javadoc)
     * @see AppInfoService#queryEnvFlag(java.lang.String)
     */
    @Override
    public ResponseVo<String> queryEnvFlag(String envName) {
        Assert.notNull(envName, "envName不能为空");

        AppEnv appEnvParam = new AppEnv();
        appEnvParam.setName(envName);
        AppEnv appEnv = envService.selectOne(appEnvParam);
        if (EnumDefinition.CommonStatus.NO.getCode().equals(appEnv.getOfflineEnv())) {
            //线上机房
            return ResponseVo.getSuccessResponse("online");

        }
        return ResponseVo.getSuccessResponse("offline");
    }

}
